﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crystal.Libs;
using Microsoft.Xna.Framework;
using Jitter;
using Microsoft.Xna.Framework.Graphics;
using Ivory;
using Crystal.libs;

namespace Crystal.Mapping
{
    [Serializable]
    public abstract class CellBase : ISelectable3D
    {
        protected partial class CellPrim : PhysicsPrim
        {
            public CellPrim(Vector3 pos)
                : base(pos)
            {
                this.IsStatic = true;
                this.AffectedByGravity = false;
                this.Rescale(Vector3.One);
            }

            public Matrix World
            {
                get
                {
                    return
                        Matrix.CreateScale(this.Scale)
                        *
                        Matrix.CreateRotationX(Rotation.X) *
                        Matrix.CreateRotationY(Rotation.Y) *
                        Matrix.CreateRotationZ(Rotation.Z)
                        *
                        Matrix.CreateTranslation(Conversion.ConvertVect(this.Position));
                }
            }
        }

        //Fields 
        [NonSerialized]
        public Game Game;        
        [NonSerialized]
        protected CellPrim CellPrimitive;

        public Vector3 CellOrigin { get { return new Vector3(CellPrimitive.Position.X, 0, CellPrimitive.Position.Z); } }
        public MazePosition MazePosition { get; private set; }

        //cTor
        public CellBase(Game game, MazePosition Position)
        {
            this.Game = game;
            this.CellPrimitive = new CellPrim(new Vector3(
                (Position.X * Globals.CellSize.X) + (Globals.CellSize.X / 2),
                0f, 
                (Position.Z * Globals.CellSize.Z) + (Globals.CellSize.Z / 2)));

            MazePosition = Position;     
        }

        //Methods                
        public virtual void DrawCell()
        {
            if (Globals.GameWorld == null)
                throw new CrystalFrameworkError(Errors.NoGameWorld);

            if (Globals.GameWorld == null)
                throw new CrystalFrameworkError(Errors.NoGameCamera);

            RenderCell();

            if (Globals.DrawPrimitivesInDebugMode)
            {
                if (Globals.GlobalDebugRenderer == null)
                    throw new CrystalFrameworkError(Errors.NoGlobalDebugDrawer);


                Globals.GlobalDebugRenderer.DrawAabb(CellPrimitive.BoundingBox.Min, CellPrimitive.BoundingBox.Max, Color.Red);
            }
        }

        public abstract void RenderCell();
        public abstract void UpdateCell(GameTime time);
        
        #region ISelectable3D
        public Jitter.Dynamics.RigidBody Body
        {
            get { return this.CellPrimitive; }
        }

        public MazePosition Position
        {
            get { return this.MazePosition; }
        }

        public SelectableState SelectionState
        {
            get;
            set;
        }

        #endregion                
    }
}
